/*
 * author Vdaras
 */

#ifndef SINGLETON_H
#define	SINGLETON_H

#include "NonCopyable.h"
#include <cstdlib>


/**
 * Using this macro you make a class singleton and non copyable.
 * to use it just place this macro after the first bracket of the class declaration;
 * ex.
 * 
 * IWantToBeSingleton.h
 * 
 * class IWantToBeSingleton : public ExamplarClass
 * {
 *      SingletonClass(IWantToBeSingleton)
 * public:
 *  ....
 * }
 * 
 * IWantToBeSingleton.cpp
 * 
 * SingletonInitialization(IWantToBeSingleton);
 * 
 * If you need to use a custom Default Constructor use SingletonClassCustomConst
 * instead.
 * 
 */
#define SingletonClass(x) public : \
static x* GetInstance(){ \
if(!instance){instance = new x;} return instance;} \
static void DeleteInstance(){if(instance)delete instance;}  \
private: x(){} \
static x* instance; \
x(const x &toCopy); \
x &operator = (const x &toAssign) { return *this; }

#define SingletonClassCustomConst(x) public :\
static x* GetInstance(){\
if(!instance){instance = new x;} \
return instance;}\
static void DeleteInstance(){if(instance)delete instance;}  \
private: x();\
static x* instance;\
x(const x &toCopy);\
x &operator = (const x &toAssign) { return *this; }

/**
 * Used to initialize static instance of the Singleton class.
 */
#define SingletonInitialization(x) x* x::instance = NULL;


//DEPRICATED
template <class T>
class Singleton : NonCopyable
{
public:
    virtual ~Singleton()
    {
    }


    static T *GetInstance()
    {
        static T* instance = NULL;

        if(!instance)
        {
            instance = new T;
        }

        return instance;
    }

protected:
    Singleton()
    {
    }
};

#endif	/* SINGLETON_H */
